#include "./BSP/REMOTE/remote.h"
#include "./SYSTEM/delay/delay.h"
#include "./SYSTEM/usart/usart.h"


TIM_HandleTypeDef g_tim4_handle;      /* ¶¨Ê±Æ÷4¾ä±ú */


/**
 * @brief       ºìÍâÒ£¿Ø³õÊ¼»¯
 *   @note      ÉèÖÃIOÒÔ¼°¶¨Ê±Æ÷µÄÊäÈë²¶»ñ
 * @param       ÎÞ
 * @retval      ÎÞ
 */
void remote_init(void)
{
    TIM_IC_InitTypeDef tim_ic_init_handle;

    g_tim4_handle.Instance = REMOTE_IN_TIMX;                    /* Í¨ÓÃ¶¨Ê±Æ÷4 */
    g_tim4_handle.Init.Prescaler = (72-1);                      /* Ô¤·ÖÆµÆ÷,1MµÄ¼ÆÊýÆµÂÊ,1us¼Ó1 */
    g_tim4_handle.Init.CounterMode = TIM_COUNTERMODE_UP;        /* ÏòÉÏ¼ÆÊýÆ÷ */
    g_tim4_handle.Init.Period = 10000;                          /* ×Ô¶¯×°ÔØÖµ */
    g_tim4_handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    HAL_TIM_IC_Init(&g_tim4_handle);
    
    /* ³õÊ¼»¯TIM4ÊäÈë²¶»ñ²ÎÊý */
    tim_ic_init_handle.ICPolarity = TIM_ICPOLARITY_RISING;      /* ÉÏÉýÑØ²¶»ñ */
    tim_ic_init_handle.ICSelection = TIM_ICSELECTION_DIRECTTI;  /* Ó³Éäµ½TI4ÉÏ */
    tim_ic_init_handle.ICPrescaler = TIM_ICPSC_DIV1;            /* ÅäÖÃÊäÈë·ÖÆµ£¬²»·ÖÆµ */
    tim_ic_init_handle.ICFilter = 0x03;                         /* IC1F=0003 8¸ö¶¨Ê±Æ÷Ê±ÖÓÖÜÆÚÂË²¨ */
    HAL_TIM_IC_ConfigChannel(&g_tim4_handle, &tim_ic_init_handle, REMOTE_IN_TIMX_CHY);/* ÅäÖÃTIM4Í¨µÀ4 */
    HAL_TIM_IC_Start_IT(&g_tim4_handle, REMOTE_IN_TIMX_CHY);    /* ¿ªÊ¼²¶»ñTIMµÄÍ¨µÀÖµ */
    __HAL_TIM_ENABLE_IT(&g_tim4_handle, TIM_IT_UPDATE);         /* Ê¹ÄÜ¸üÐÂÖÐ¶Ï */
}

/**
 * @brief       ¶¨Ê±Æ÷4µ×²ãÇý¶¯£¬Ê±ÖÓÊ¹ÄÜ£¬Òý½ÅÅäÖÃ
 * @param       htim:¶¨Ê±Æ÷¾ä±ú
 * @note        ´Ëº¯Êý»á±»HAL_TIM_IC_Init()µ÷ÓÃ
 * @retval      ÎÞ
 */
void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim)
{
    if(htim->Instance == REMOTE_IN_TIMX)
    {
        GPIO_InitTypeDef gpio_init_struct;
        
        REMOTE_IN_GPIO_CLK_ENABLE();            /* ºìÍâ½ÓÈëÒý½ÅGPIOÊ±ÖÓÊ¹ÄÜ */
        REMOTE_IN_TIMX_CHY_CLK_ENABLE();        /* ¶¨Ê±Æ÷Ê±ÖÓÊ¹ÄÜ */
        __HAL_AFIO_REMAP_TIM4_DISABLE();        /* ÕâÀïÓÃµÄÊÇPB9/TIM4_CH4£¬²Î¿¼AFIO_MAPR¼Ä´æÆ÷µÄÉèÖÃ */
        
        gpio_init_struct.Pin = REMOTE_IN_GPIO_PIN;
        gpio_init_struct.Mode = GPIO_MODE_AF_INPUT;             /* ¸´ÓÃÊäÈë */
        gpio_init_struct.Pull = GPIO_PULLUP;                    /* ÉÏÀ­ */
        gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;          /* ¸ßËÙ */
        HAL_GPIO_Init(REMOTE_IN_GPIO_PORT, &gpio_init_struct);  /* ³õÊ¼»¯¶¨Ê±Æ÷Í¨µÀÒý½Å */

        HAL_NVIC_SetPriority(REMOTE_IN_TIMX_IRQn, 1, 3);        /* ÉèÖÃÖÐ¶ÏÓÅÏÈ¼¶£¬ÇÀÕ¼ÓÅÏÈ¼¶1£¬×ÓÓÅÏÈ¼¶3 */
        HAL_NVIC_EnableIRQ(REMOTE_IN_TIMX_IRQn);                /* ¿ªÆôITM4ÖÐ¶Ï */
    }

}

/* Ò£¿ØÆ÷½ÓÊÕ×´Ì¬
 * [7]  : ÊÕµ½ÁËÒýµ¼Âë±êÖ¾
 * [6]  : µÃµ½ÁËÒ»¸ö°´¼üµÄËùÓÐÐÅÏ¢
 * [5]  : ±£Áô
 * [4]  : ±ê¼ÇÉÏÉýÑØÊÇ·ñÒÑ¾­±»²¶»ñ
 * [3:0]: Òç³ö¼ÆÊ±Æ÷
 */
uint8_t g_remote_sta = 0;
uint32_t g_remote_data = 0; /* ºìÍâ½ÓÊÕµ½µÄÊý¾Ý */
uint8_t  g_remote_cnt = 0;  /* °´¼ü°´ÏÂµÄ´ÎÊý */

/**
 * @brief       ¶¨Ê±Æ÷ÖÐ¶Ï·þÎñº¯Êý
 * @param       ÎÞ
 * @retval      ÎÞ
 */
void REMOTE_IN_TIMX_IRQHandler(void)
{
    HAL_TIM_IRQHandler(&g_tim4_handle); /* ¶¨Ê±Æ÷¹²ÓÃ´¦Àíº¯Êý */
}

/**
 * @brief       ¶¨Ê±Æ÷¸üÐÂÖÐ¶Ï»Øµ÷º¯Êý
 * @param       htim:¶¨Ê±Æ÷¾ä±ú
 * @retval      ÎÞ
 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if (htim->Instance == REMOTE_IN_TIMX)
    {
        if (g_remote_sta & 0x80)      /* ÉÏ´ÎÓÐÊý¾Ý±»½ÓÊÕµ½ÁË */
        {
            g_remote_sta &= ~0X10;    /* È¡ÏûÉÏÉýÑØÒÑ¾­±»²¶»ñ±ê¼Ç */

            if ((g_remote_sta & 0X0F) == 0X00)
            {
                g_remote_sta |= 1 << 6; /* ±ê¼ÇÒÑ¾­Íê³ÉÒ»´Î°´¼üµÄ¼üÖµÐÅÏ¢²É¼¯ */
            }
            
            if ((g_remote_sta & 0X0F) < 14)
            {
                g_remote_sta++;
            }
            else
            {
                g_remote_sta &= ~(1 << 7);    /* Çå¿ÕÒýµ¼±êÊ¶ */
                g_remote_sta &= 0XF0;         /* Çå¿Õ¼ÆÊýÆ÷ */
            }
        }
    }
}

/**
 * @brief       ¶¨Ê±Æ÷ÊäÈë²¶»ñÖÐ¶Ï»Øµ÷º¯Êý
 * @param       htim:¶¨Ê±Æ÷¾ä±ú
 * @retval      ÎÞ
 */
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
    if (htim->Instance == REMOTE_IN_TIMX)
    {
        uint16_t dval;  /* ÏÂ½µÑØÊ±¼ÆÊýÆ÷µÄÖµ */
        
        if (RDATA)      /* ÉÏÉýÑØ²¶»ñ */
        {
            __HAL_TIM_SET_CAPTUREPOLARITY(&g_tim4_handle,REMOTE_IN_TIMX_CHY,TIM_INPUTCHANNELPOLARITY_FALLING);//CC4P=1 ÉèÖÃÎªÏÂ½µÑØ²¶»ñ
            __HAL_TIM_SET_COUNTER(&g_tim4_handle, 0);  /* Çå¿Õ¶¨Ê±Æ÷Öµ */
            g_remote_sta |= 0X10;                      /* ±ê¼ÇÉÏÉýÑØÒÑ¾­±»²¶»ñ */
        }
        else           /* ÏÂ½µÑØ²¶»ñ */
        {
            dval=HAL_TIM_ReadCapturedValue(&g_tim4_handle, REMOTE_IN_TIMX_CHY);                /* ¶ÁÈ¡CCR4Ò²¿ÉÒÔÇåCC4IF±êÖ¾Î» */
            __HAL_TIM_SET_CAPTUREPOLARITY(&g_tim4_handle, REMOTE_IN_TIMX_CHY, TIM_INPUTCHANNELPOLARITY_RISING);/* ÅäÖÃTIM4Í¨µÀ4ÉÏÉýÑØ²¶»ñ */

            if (g_remote_sta & 0X10)        /* Íê³ÉÒ»´Î¸ßµçÆ½²¶»ñ */
            {
                if (g_remote_sta & 0X80)    /* ½ÓÊÕµ½ÁËÒýµ¼Âë */
                {

                    if (dval > 300 && dval < 800)           /* 560Îª±ê×¼Öµ,560us */
                    {
                        g_remote_data >>= 1;                /* ÓÒÒÆÒ»Î» */
                        g_remote_data &= ~(0x80000000);     /* ½ÓÊÕµ½0 */
                    }
                    else if (dval > 1400 && dval < 1800)    /* 1680Îª±ê×¼Öµ,1680us */
                    {
                        g_remote_data >>= 1;                /* ÓÒÒÆÒ»Î» */
                        g_remote_data |= 0x80000000;        /* ½ÓÊÕµ½1 */
                    }
                    else if (dval > 2000 && dval < 3000)    /* µÃµ½°´¼ü¼üÖµÔö¼ÓµÄÐÅÏ¢ 2500Îª±ê×¼Öµ2.5ms */
                    {
                        g_remote_cnt++;         /* °´¼ü´ÎÊýÔö¼Ó1´Î */
                        g_remote_sta &= 0XF0;   /* Çå¿Õ¼ÆÊ±Æ÷ */
                    }
                }
                else if (dval > 4200 && dval < 4700)    /* 4500Îª±ê×¼Öµ4.5ms */
                {
                    g_remote_sta |= 1 << 7; /* ±ê¼Ç³É¹¦½ÓÊÕµ½ÁËÒýµ¼Âë */
                    g_remote_cnt = 0;       /* Çå³ý°´¼ü´ÎÊý¼ÆÊýÆ÷ */
                }
            }

            g_remote_sta&=~(1<<4);
        }
    }
}

/**
 * @brief       ´¦ÀíºìÍâ°´¼ü(ÀàËÆ°´¼üÉ¨Ãè)
 * @param       ÎÞ
 * @retval      0   , Ã»ÓÐÈÎºÎ°´¼ü°´ÏÂ
 *              ÆäËû, °´ÏÂµÄ°´¼ü¼üÖµ
 */
uint8_t remote_scan(void)
{
    uint8_t sta = 0;
    uint8_t t1, t2;

    if (g_remote_sta & (1 << 6))    /* µÃµ½Ò»¸ö°´¼üµÄËùÓÐÐÅÏ¢ÁË */
    {
        t1 = g_remote_data;                 /* µÃµ½µØÖ·Âë */
        t2 = (g_remote_data >> 8) & 0xff;   /* µÃµ½µØÖ··´Âë */

        if ((t1 == (uint8_t)~t2) && t1 == REMOTE_ID)    /* ¼ìÑéÒ£¿ØÊ¶±ðÂë(ID)¼°µØÖ· */
        {
            t1 = (g_remote_data >> 16) & 0xff;
            t2 = (g_remote_data >> 24) & 0xff;

            if (t1 == (uint8_t)~t2)
            {
                sta = t1;           /* ¼üÖµÕýÈ· */
            }
        }

        if ((sta == 0) || ((g_remote_sta & 0X80) == 0)) /* °´¼üÊý¾Ý´íÎó/Ò£¿ØÒÑ¾­Ã»ÓÐ°´ÏÂÁË */
        {
            g_remote_sta &= ~(1 << 6);  /* Çå³ý½ÓÊÕµ½ÓÐÐ§°´¼ü±êÊ¶ */
            g_remote_cnt = 0;           /* Çå³ý°´¼ü´ÎÊý¼ÆÊýÆ÷ */
        }
    }

    return sta;
}